"use strict";
if (!Array.prototype.forEach) {
	Array.prototype.forEach = function(callback, thisArg) {
		var T, k;
		if (this == null) {
			throw new TypeError(" this is null or not defined");
		}
		var O = Object(this);
		var len = O.length >>> 0; // Hack to convert O.length to a UInt32
		if ({}.toString.call(callback) != "[object Function]") {
			throw new TypeError(callback + " is not a function");
		}
		if (thisArg) {
			T = thisArg;
		}
		k = 0;
		while (k < len) {
			var kValue;
			if (k in O) {
				kValue = O[k];
				callback.call(T, kValue, k, O);
			}
			k++;
		}
	};
}
(function($, mango, undefined) {

	// ! Set forms
	mango.ready(function() {

		// - Set defaults
		$.validator.setDefaults({

			// Do not ignore chosen-selects | datepicker mirrors | checkboxes |
			// radio buttons
			ignore : ':hidden:not(select):not(input.mirror):not(:checkbox):not(:radio):not(.dualselects),.ignore',

			// If a field is switches from invalid to valid
			success : function(label) {
				// Change icon from error to valid
				$(label).prev().filter('.error-icon').removeClass('error-icon').addClass('valid-icon');

				// If file input: remove 'error' from '.customfile'
				$(label).prev('.customfile').removeClass('error');
			},

			// Where to place the error labels
			errorPlacement : function($error, $element) {

				if ($element.hasClass('customfile-input-hidden')) {

				} else if ($element.hasClass('customfile-input-hidden')) {

					$error.insertAfter($element.parent().addClass('error'));

					// Password meter || Textarea || Spinner || Inline
					// Datepicker || Checkbox || Radiobutton: No icon
				} else if ($element.is(':password.meter') || $element.is('textarea') || $element.is('.ui-spinner-input') || $element.is('input.mirror')) {

					$error.insertAfter($element);

					// Checkbox: No icon, after replacement
				} else if ($element.is(':checkbox') || $element.is(':radio')) {

					if ($element.is(':checkbox')) {
						$error.insertAfter($element);
					} else {
						// Find last radion button
						$error.insertAfter($('[name=' + $element[0].name + ']').last());
					}

					// Select: No icon, insert after select box replacement
				} else if ($element.is('select') || $element.is('select.chzn-done') || $element.is('.dualselects')) {

					$error.insertAfter($element.next());

					// Default: Insert after element, show icon
				} else {

					$error.insertAfter($element);

					// Show icon
					var $icon = $('<div class="error-icon icon" />').insertAfter($element).position({
						my : 'right',
						at : 'right',
						of : $element,
						offset : '-5 0',
						overflow : 'none',
						using : function(pos) {
							// Figure out the right and bottom css properties
							var offsetWidth = $(this).offsetParent().outerWidth();
							var right = offsetWidth - pos.left - $(this).outerWidth();

							// Position the element so that right and bottom are
							// set.
							$(this).css({
								left : '',
								right : right,
								top : pos.top
							});
						}
					});

				}
			},

			// Reposition error labels and hide unneeded labels
			showErrors : function(map, list) {
				var self = this;

				this.defaultShowErrors();

				list.forEach(function(err) {
					var $element = $(err.element), $error = self.errorsFor(err.element);

					// Select || Textarea || File Input || Inline Datepicker ||
					// Checkbox || Radio button: Inline Error Labels
					if ($element.data('errorType') == 'inline' || $element.is('select') || $element.is('textarea') || $element.hasClass('customfile-input-hidden') || $element.is('input.mirror') || $element.is(':checkbox') || $element.is(':radio') || $element.is('.dualselect')) {

						// Get element to which the error label is aligned
						var $of;
						if ($element.is('select')) {
							$of = $element.next();
						} else if ($element.is(':checkbox') || $element.is(':radio')) {
							if ($element.is(':checkbox')) {
								$of = $element.next();
							} else {
								// Find last radio button
								$of = $('[name=' + $element[0].name + ']').last().next().next();
							}
							$error.css('display', 'block');
						} else if ($element.is('input.mirror')) {
							$of = $element.prev();
						} else {
							$of = $element;
						}

						$error.addClass('inline').position({
							my : 'left top',
							at : 'left bottom',
							of : $of,
							offset : '0 5',
							collision : 'none'
						});

						if (!($element.is(':checkbox') && $element.is(':radio'))) {
							$error.css('left', '');
						}

						// Default: Tooltip labels
					} else {

						$error.position({
							my : 'right top',
							at : 'right bottom',
							of : $element,
							offset : '1 8',
							using : function(pos) {
								// Figure out the right and bottom css
								// properties
								var offsetWidth = $(this).offsetParent().outerWidth();
								var right = offsetWidth - pos.left - $(this).outerWidth();

								// Position the element so that right and bottom
								// are set.
								$(this).css({
									left : '',
									right : right,
									top : pos.top
								});
							}
						});

					} // End if

					// Switch icon from valid to error
					$error.prev().filter('.valid-icon').removeClass('valid-icon').addClass('error-icon');

					// Hide error labe on .noerror
					if ($element.hasClass('noerror')) {
						$error.hide();
						$element.next('.icon').hide();
					}
				});

				// Hide success labels
				this.successList.forEach(function(el) {
					self.errorsFor(el).hide();
				});

			}
		});

		// - Validate
		$('form.validate').each(function() {
			$(this).validate({
				submitHandler : function(form) {
					$(this).data('submit') ? $(this).data('submit')() : form.submit();
				}
			});
		});

		// - Reset validation on form reset
		$('form.validate').on('reset', function() {
			var $form = $(this);
			$form.validate().resetForm();
			$form.find('label.error').remove().end().find('.error-icon').remove().end().find('.valid-icon').remove().end().find('.valid').removeClass('valid').end().find('.customfile.error').removeClass('error');
		});

		// ! Polyfill: 'form' tag on <input>s
		if (!('form' in document.createElement('input'))) {
			$('input:submit').each(function() {
				var $el = $(this);
				if ($el.attr('form')) {
					$el.click(function() {
						$('#' + $el.attr('form')).submit();
					});
				}
			});
			$('input:reset').each(function() {
				var $el = $(this);
				if ($el.attr('form')) {
					$el.click(function() {
						$('#' + $el.attr('form'))[0].reset();
					});
				}
			});
		}

	});

	// ! Loading screen
	mango.ready(function() {
		$('.tabbedBox').tabs({
			beforeActivate : function(event, ui) {
				var beforeClickEvent = ui.newTab.data("beforeclick");

				if (beforeClickEvent && beforeClickEvent != "") {
					var beforeClickEventResult = eval(beforeClickEvent);
					if (beforeClickEventResult == false) {
						return false;
					}
				}
			}
		});
		$('#loading').hide();
		isperp.initElement();
		$('a.button.disabled').click(function() {
			return false;
		});

		// - Start counting when #loading fadeout is finished
		setTimeout(function() {

			// ! The lock screen
			// - Start only, if required html is complete and we don't have a
			// phone
			if ($('#lock-screen').length && $('#btn-lock').length && !mango.utils.isPhone) {
				mango.lock();
			}

		}, mango.config.fxSpeed);
	});

})(jQuery, $$);
